package com.easylinkin.sm.service.impl;

import com.easylinkin.core.tree.TreeSelect;
import com.easylinkin.sm.constant.PrivilegeConstant;
import com.easylinkin.sm.entity.Privilege;
import com.easylinkin.sm.entity.Role;
import com.easylinkin.sm.entity.User;
import com.easylinkin.sm.repository.PrivilegeRepository;
import com.easylinkin.sm.service.PrivilegeService;
import com.easylinkin.sm.service.RoleService;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import site.morn.boot.data.CrudServiceSupport;
import site.morn.boot.jpa.SpecificationFunction;
import site.morn.core.CriteriaMap;
import site.morn.framework.context.AccountContext;
import site.morn.framework.context.dto.BaseLoginInfo;
import site.morn.framework.entity.BasePrivilege.Fields;

/**
 * 权限服务
 *
 * @author wujie
 * @since 0.1.1,  2019/08/28
 */
@Slf4j
@Service
@Transactional
public class PrivilegeServiceImpl extends
    CrudServiceSupport<Privilege, Long, PrivilegeRepository> implements PrivilegeService {

  @Autowired
  RoleService roleService;

  @Override
  public List<TreeSelect> searchPrivilegeTree(Integer disabled) {
    List<TreeSelect> trees = new ArrayList();
    // 根据当前用户的登录角色过滤
    BaseLoginInfo baseLoginInfo = AccountContext.loginInfo();
    List<Privilege> privilegesList = (List<Privilege>) baseLoginInfo.getPrivileges();
    List<Privilege> privileges = repository().findAllByParentId(0L);
    if (!CollectionUtils.isEmpty(privileges)) {
      privileges.forEach(privilege -> {
        TreeSelect tree = this.privilegeToTreeSelect(privilege, disabled);
        this.getTree(tree, privilegesList, disabled);
        trees.add(tree);
      });

    }
    return trees;
  }

  @Override
  public Collection<Privilege> getCurrent() {
    // 获取当前用户
    User user = AccountContext.currentUser();
    Collection<Role> roles = roleService.getByUserId(user.getId());
    return roles.stream().flatMap(role -> role.getPrivileges().stream()).collect(Collectors.toList());
  }

  private void getTree(TreeSelect<Privilege> treeNode, List<Privilege> privilegesList, Integer disabled){
    List<Privilege> filterList = privilegesList.stream().filter(privilege -> privilege.getParentId().equals(treeNode.getId())).collect(Collectors.toList());
    if (!filterList.isEmpty()) {
      List<TreeSelect<Privilege>> children = new ArrayList();
      filterList.forEach(privilege -> {
        TreeSelect<Privilege> currentTreeNode = this.privilegeToTreeSelect(privilege, disabled);
        children.add(currentTreeNode);
        this.getTree(currentTreeNode, privilegesList, disabled);
      });
      treeNode.setChildren(children);
    }
  }

  private TreeSelect<Privilege> privilegeToTreeSelect(Privilege privilege, Integer disabled){
    TreeSelect<Privilege> treeSelect = new TreeSelect();
    treeSelect.setId(privilege.getId());
    treeSelect.setParentId(privilege.getParentId());
    treeSelect.setLabel(privilege.getName());
    treeSelect.setData(privilege);
    treeSelect.setIsDisabled(disabled != 0);
    return treeSelect;
  }

  @Override
  protected SpecificationFunction searchSpecificationFunction(Privilege model, CriteriaMap attach) {
    return (reference, restrain, predicate) -> {
      model.setType(PrivilegeConstant.PRIVILEGE_TYPE_BUTTON);
      restrain.appendAnd(predicate.eq(Fields.parentId)).appendAnd(predicate.notEqual(Fields.type));
    };
  }
}
